/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.gitee.fdc.base.service;

import com.github.pagehelper.PageHelper;
import java.util.List;
import java.util.Map;
import com.gitee.fdc.base.entity.BaseEntity;
import com.gitee.fdc.base.entity.audit.AuditAware;
import com.gitee.fdc.base.entity.audit.Auditable;
import com.gitee.fdc.base.entity.audit.DefaultAuditAware;
import com.gitee.fdc.mapper.entity.SbbsExample;
import java.sql.Timestamp;
import com.gitee.fdc.kits.SpringContextHolder;
import com.gitee.fdc.web.page.PageKit;
import com.gitee.fdc.web.page.PageReq;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.entity.EntityTable;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import com.gitee.fdc.mapper.SbbsMapper;
import java.io.Serializable;

/**
 *
 * @author qskj
 * @param <T>
 */
public class BaseServiceImple<T extends BaseEntity, ID extends Serializable> implements DeleteLogicService<T, ID> {

    SbbsMapper<T> dao;
    Map<String, EntityColumn> propertyMap;
    Class entityClass;

    public void init(Class entityClass, SbbsMapper dao) {
        this.dao = dao;
        this.entityClass = entityClass;
        EntityTable table = EntityHelper.getEntityTable(entityClass);
        this.propertyMap = table.getPropertyMap();
    }

    public Class getEntityClass() {
        return entityClass;
    }

    @Override
    @Transactional(readOnly = false)
    public int save(T entity) {
        if (entity.getId() == null) {
            this.processAuditInofBeforeInsert(entity);
            return this.dao.insert(entity);
        } else {

            this.processAuditInofBeforeUpdate(entity);
            return this.dao.updateByPrimaryKey(entity);
        }
    }

    @Override
    @Transactional(readOnly = false)
    public int saveSelective(T entity) {
        if (entity.getId() == null) {
            this.processAuditInofBeforeInsert(entity);
            return this.dao.insertSelective(entity);
        } else {

            this.processAuditInofBeforeUpdate(entity);
            return this.dao.updateByPrimaryKeySelective(entity);
        }
    }

    @Override
    @Transactional(readOnly = false)
    public int updateByPrimaryKeySelective(T entity) {
        this.processAuditInofBeforeUpdate(entity);
        return this.dao.updateByPrimaryKeySelective(entity);
    }

    @Override
    public T findById(ID id) {
        return this.dao.selectByPrimaryKey(id);
    }

    @Override
    @Transactional(readOnly = false)
    public int deleteById(ID id) {
        return this.dao.deleteByPrimaryKey(id);
    }

    @Override
    @Transactional(readOnly = false)
    public int unDeleteById(ID id) {
        return this.dao.unDeleteByPrimaryKey(id);
    }

    @Override
    @Transactional(readOnly = false)
    public int deleteByIds(String ids) {
        return this.dao.deleteByIds(ids);
    }

    @Override
    @Transactional(readOnly = false)
    public int delete(T entity) {
        return this.dao.delete(entity);
    }

    @Override
    public List findAll() {
        return dao.selectAll();
    }

    @Override
    public List findAllPaged() {
        this.pageAble();
        List l = dao.selectAll();
        return l;
    }

    protected void pageAble() {
        PageReq pr = PageKit.getPageReqs();
        PageHelper.offsetPage(pr.getOffset(), pr.getLimit());
        if (pr.isOpenSort()) {
            String sort = pr.getSort();
            String sortcolumn = this.propertyMap.get(sort).getColumn();
            pr.setSort(sortcolumn);
            PageHelper.orderBy(pr.getOrderBy());
        }
    }
    private AuditAware aduitAware;

    private AuditAware getAuditAware() {
        if (aduitAware == null) {
            aduitAware = SpringContextHolder.getBean(AuditAware.class);
            if (aduitAware == null) {
                aduitAware = new DefaultAuditAware();
            }
            return this.aduitAware;
        } else {
            return this.aduitAware;
        }
    }

    private void processAuditInofBeforeInsert(T entity) {
        if (entity instanceof Auditable) {
            ((Auditable) entity).setCreateUser(this.getAuditAware().getCurrentUserName());
            ((Auditable) entity).setModifyUser(this.getAuditAware().getCurrentUserName());
            Timestamp time1 = new Timestamp(System.currentTimeMillis());
            ((Auditable) entity).setCreateDate(time1);
            ((Auditable) entity).setModifyDate(time1);
        } else {
            return;
        }
    }

    private void processAuditInofBeforeUpdate(T entity) {
        if (entity instanceof Auditable) {
            ((Auditable) entity).setModifyUser(this.getAuditAware().getCurrentUserName());
            Timestamp time1 = new Timestamp(System.currentTimeMillis());
            ((Auditable) entity).setModifyDate(time1);
        } else {
            return;
        }
    }

    @Override
    public boolean isPropertyUnique(ID id, String propName, Object propValue) {
        Example e = new SbbsExample(entityClass);
        e.createCriteria().andEqualTo(propName, propValue);
        T l = this.dao.selectOneByExample(e);
        if (l == null) {
            return true;
        }
        if (id == null) {
            return l == null;
        } else {
            return id.equals(l.getId());
        }
    }

    @Override
    public T findByIdDespiteDelFlag(ID id) {
        return this.dao.selectByPrimaryKeyDispiteDelFlag(id);
    }

    @Override
    @Transactional(readOnly = false)
    public int updateByPrimaryKeySelectiveDespiteDelFlag(T entity) {
        this.processAuditInofBeforeUpdate(entity);
        return this.dao.updateByPrimaryKeySelectiveDispiteDelFlag(entity);
    }

}
